<script setup>
import { nextTick, ref } from 'vue'
import { Panel, VueFlow, useVueFlow } from '@vue-flow/core'
import { Background } from '@vue-flow/background'
import Icon from './icon.vue'

import { initialEdges, initialNodes } from './initial-elements.ts'
import { useLayout } from './use-layout.ts'
import CustomNode from './components/custom-node.vue'
import AddButtonNode from './components/add-button-node.vue'
import StartNode from './components/start-node.vue'
import EndNode from './components/end-node.vue'
import ApprovalNode from './components/approval-node.vue'
import CcNode from './components/cc-node.vue'
import MutexDecisionNode from './components/mutex-decision-node.vue'
import MutexBranchNode from './components/mutex-branch-node.vue'

const nodes = ref([])
const edges = ref([])

const { layout } = useLayout()
const { fitView } = useVueFlow()

// 初始化节点和边，在每条边上插入添加按钮节点
function initializeNodesAndEdges() {
  const newNodes = [...initialNodes]
  const newEdges = []
  let addBtnCounter = 0

  // 为每条边插入一个添加按钮节点
  initialEdges.forEach(edge => {
    const addBtnNodeId = `add-btn-${addBtnCounter++}`

    // 创建添加按钮节点
    newNodes.push({
      id: addBtnNodeId,
      type: 'add-button',
      position: { x: 0, y: 0 },
      data: {},
    })

    // 原边 source -> target 变成：
    // source -> addBtn
    newEdges.push({
      id: `${edge.source}->add-btn-${addBtnNodeId}`,
      source: edge.source,
      target: addBtnNodeId,
    })

    // addBtn -> target
    newEdges.push({
      id: `${addBtnNodeId}->${edge.target}`,
      source: addBtnNodeId,
      target: edge.target,
    })
  })

  nodes.value = newNodes
  edges.value = newEdges
}

async function layoutGraph() {
  nodes.value = layout(nodes.value, edges.value)

  nextTick(() => {
    fitView()
  })
}

// 添加节点到指定位置（替换添加按钮节点）
function addNodeAfter(addBtnNodeId, nodeType) {
  const newNodeId = `node-${Date.now()}`

  // 节点类型映射
  const nodeTypeMap = {
    'approval': 'approval',
    'cc': 'cc',
    'mutex': 'mutex',
  }

  const labelMap = {
    'approval': '审批',
    'cc': '抄送',
    'mutex': '互斥条件',
  }

  const descriptionMap = {
    'approval': '未设置审批对象',
    'cc': '未设置抄送对象',
    'mutex': '添加条件分支',
  }

  // 如果是互斥节点，需要特殊处理
  if (nodeType === 'mutex') {
    addMutexNode(addBtnNodeId, newNodeId);
    return;
  }

  // 创建新节点
  const newNode = {
    id: newNodeId,
    type: nodeTypeMap[nodeType] || 'approval',
    position: { x: 0, y: 0 },
    data: {
      label: labelMap[nodeType] || '新节点',
      description: descriptionMap[nodeType] || '点击编辑描述',
    },
  }

  // 找到连接到当前添加按钮节点的边
  const incomingEdge = edges.value.find(e => e.target === addBtnNodeId)
  const outgoingEdge = edges.value.find(e => e.source === addBtnNodeId)

  if (!incomingEdge) return

  const sourceNodeId = incomingEdge.source
  const targetNodeId = outgoingEdge?.target

  // 移除旧的添加按钮节点
  nodes.value = nodes.value.filter(n => n.id !== addBtnNodeId)

  // 移除连接到旧添加按钮的边
  edges.value = edges.value.filter(e => e.source !== addBtnNodeId && e.target !== addBtnNodeId)

  // 添加新节点
  nodes.value.push(newNode)

  // 创建新的添加按钮节点（在新节点之前）
  const newAddBtnId1 = `add-btn-${Date.now()}-before`
  nodes.value.push({
    id: newAddBtnId1,
    type: 'add-button',
    position: { x: 0, y: 0 },
    data: {},
  })

  // 重新连接：源节点 -> 添加按钮1 -> 新节点
  edges.value.push({
    id: `${sourceNodeId}->${newAddBtnId1}`,
    source: sourceNodeId,
    target: newAddBtnId1,
  })

  edges.value.push({
    id: `${newAddBtnId1}->${newNodeId}`,
    source: newAddBtnId1,
    target: newNodeId,
  })

  // 如果有下游节点，创建：新节点 -> 添加按钮2 -> 下游节点
  if (targetNodeId) {
    const newAddBtnId2 = `add-btn-${Date.now()}-after`
    nodes.value.push({
      id: newAddBtnId2,
      type: 'add-button',
      position: { x: 0, y: 0 },
      data: {},
    })

    edges.value.push({
      id: `${newNodeId}->${newAddBtnId2}`,
      source: newNodeId,
      target: newAddBtnId2,
    })

    edges.value.push({
      id: `${newAddBtnId2}->${targetNodeId}`,
      source: newAddBtnId2,
      target: targetNodeId,
    })
  }

  // 重新计算布局
  nextTick(() => {
    layoutGraph()
  })
}

// 添加互斥节点的特殊处理函数
function addMutexNode(addBtnNodeId, mutexIdBase) {
  const timestamp = Date.now()
  const mutexId = `mutex-${timestamp}`
  
  // 找到连接到当前添加按钮节点的边
  const incomingEdge = edges.value.find(e => e.target === addBtnNodeId)
  const outgoingEdge = edges.value.find(e => e.source === addBtnNodeId)

  if (!incomingEdge) return

  const sourceNodeId = incomingEdge.source
  const targetNodeId = outgoingEdge?.target

  // 移除旧的添加按钮节点
  nodes.value = nodes.value.filter(n => n.id !== addBtnNodeId)
  edges.value = edges.value.filter(e => e.source !== addBtnNodeId && e.target !== addBtnNodeId)

  // 1. 创建 mutex-decision 节点（添加条件按钮）
  const decisionNodeId = `${mutexId}-decision`
  nodes.value.push({
    id: decisionNodeId,
    type: 'mutex-decision',
    position: { x: 0, y: 0 },
    data: {
      label: '添加条件',
      mutexId: mutexId,
    },
  })

  // 2. 创建初始的条件分支节点
  const branch1Id = `${mutexId}-branch-1`
  const defaultBranchId = `${mutexId}-branch-default`

  nodes.value.push({
    id: branch1Id,
    type: 'mutex-branch',
    position: { x: 0, y: 0 },
    data: {
      label: '条件2',
      description: '已设置 (1) 个条件组',
      isDefault: false,
    },
  })

  nodes.value.push({
    id: defaultBranchId,
    type: 'mutex-branch',
    position: { x: 0, y: 0 },
    data: {
      label: '默认条件',
      description: '不满足条件时,进入默认条件',
      isDefault: true,
    },
  })

  // 3. 在每个条件分支后创建 add-button 节点
  const addBtn1Id = `${mutexId}-add-btn-1`
  const addBtn2Id = `${mutexId}-add-btn-default`

  nodes.value.push({
    id: addBtn1Id,
    type: 'add-button',
    position: { x: 0, y: 0 },
    data: {},
  })

  nodes.value.push({
    id: addBtn2Id,
    type: 'add-button',
    position: { x: 0, y: 0 },
    data: {},
  })

  // 4. 创建边连接
  // 上游节点 -> decision 节点
  edges.value.push({
    id: `${sourceNodeId}->${decisionNodeId}`,
    source: sourceNodeId,
    target: decisionNodeId,
  })

  // decision -> 条件1
  edges.value.push({
    id: `${decisionNodeId}->${branch1Id}`,
    source: decisionNodeId,
    target: branch1Id,
  })

  // decision -> 默认条件
  edges.value.push({
    id: `${decisionNodeId}->${defaultBranchId}`,
    source: decisionNodeId,
    target: defaultBranchId,
  })

  // 条件1 -> add-button
  edges.value.push({
    id: `${branch1Id}->${addBtn1Id}`,
    source: branch1Id,
    target: addBtn1Id,
  })

  // 默认条件 -> add-button
  edges.value.push({
    id: `${defaultBranchId}->${addBtn2Id}`,
    source: defaultBranchId,
    target: addBtn2Id,
  })

  // 每个分支的 add-button 直接连接到下游节点（互斥分支只会走一条路径）
  if (targetNodeId) {
    edges.value.push({
      id: `${addBtn1Id}->${targetNodeId}`,
      source: addBtn1Id,
      target: targetNodeId,
    })

    edges.value.push({
      id: `${addBtn2Id}->${targetNodeId}`,
      source: addBtn2Id,
      target: targetNodeId,
    })
  }

  // 重新计算布局
  nextTick(() => {
    layoutGraph()
  })
}

// 删除互斥节点（包括所有分支和相关节点）
function deleteMutexNode(decisionNodeId) {
  const decisionNode = nodes.value.find(n => n.id === decisionNodeId)
  if (!decisionNode) return
  
  const mutexId = decisionNode.data.mutexId || decisionNodeId.replace('-decision', '')
  
  // 找到所有相关节点
  const relatedNodeIds = nodes.value
    .filter(n => n.id.startsWith(mutexId))
    .map(n => n.id)
  
  // 找到 decision 节点的上游节点
  const incomingEdge = edges.value.find(e => e.target === decisionNodeId)
  const upstreamNodeId = incomingEdge?.source
  
  // 找到任意一个分支的下游节点（所有分支都应该指向同一个下游节点）
  let downstreamNodeId = null
  const branchAddBtns = nodes.value.filter(n => 
    n.id.startsWith(`${mutexId}-add-btn-`) && n.type === 'add-button'
  )
  if (branchAddBtns.length > 0) {
    const edge = edges.value.find(e => e.source === branchAddBtns[0].id)
    if (edge) {
      downstreamNodeId = edge.target
    }
  }
  
  // 删除所有相关节点
  nodes.value = nodes.value.filter(n => !relatedNodeIds.includes(n.id))
  
  // 删除所有相关的边
  edges.value = edges.value.filter(e =>
    !relatedNodeIds.includes(e.source) && !relatedNodeIds.includes(e.target)
  )
  
  // 如果有上下游节点，在它们之间添加新的添加按钮
  if (upstreamNodeId && downstreamNodeId) {
    const newAddBtnId = `add-btn-${Date.now()}`
    nodes.value.push({
      id: newAddBtnId,
      type: 'add-button',
      position: { x: 0, y: 0 },
      data: {},
    })
    
    edges.value.push({
      id: `${upstreamNodeId}->${newAddBtnId}`,
      source: upstreamNodeId,
      target: newAddBtnId,
    })
    
    edges.value.push({
      id: `${newAddBtnId}->${downstreamNodeId}`,
      source: newAddBtnId,
      target: downstreamNodeId,
    })
  }
  
  // 重新计算布局
  nextTick(() => {
    layoutGraph()
  })
}

// 添加条件分支
function addCondition(mutexId) {
  const timestamp = Date.now()
  const newBranchId = `${mutexId}-branch-${timestamp}`
  const newAddBtnId = `${mutexId}-add-btn-${timestamp}`
  
  // 找到 decision 节点
  const decisionNodeId = `${mutexId}-decision`
  
  // 计算当前已有的条件数量
  const existingBranches = nodes.value.filter(n => 
    n.id.startsWith(`${mutexId}-branch-`) && n.type === 'mutex-branch'
  )
  const branchNumber = existingBranches.length + 1
  
  // 创建新的条件分支节点
  nodes.value.push({
    id: newBranchId,
    type: 'mutex-branch',
    position: { x: 0, y: 0 },
    data: {
      label: `条件${branchNumber}`,
      description: '已设置 (1) 个条件组',
      isDefault: false,
    },
  })
  
  // 创建新的 add-button 节点
  nodes.value.push({
    id: newAddBtnId,
    type: 'add-button',
    position: { x: 0, y: 0 },
    data: {},
  })
  
  // 找到其他分支的下游节点（所有分支应该指向同一个下游节点）
  const existingBranchAddBtn = nodes.value.find(n => 
    n.id.startsWith(`${mutexId}-add-btn-`) && n.type === 'add-button'
  )
  let downstreamNodeId = null
  if (existingBranchAddBtn) {
    const edge = edges.value.find(e => e.source === existingBranchAddBtn.id)
    if (edge) {
      downstreamNodeId = edge.target
    }
  }
  
  // 创建边连接
  // decision -> 新分支
  edges.value.push({
    id: `${decisionNodeId}->${newBranchId}`,
    source: decisionNodeId,
    target: newBranchId,
  })
  
  // 新分支 -> add-button
  edges.value.push({
    id: `${newBranchId}->${newAddBtnId}`,
    source: newBranchId,
    target: newAddBtnId,
  })
  
  // 新分支的 add-button 直接连接到下游节点
  if (downstreamNodeId) {
    edges.value.push({
      id: `${newAddBtnId}->${downstreamNodeId}`,
      source: newAddBtnId,
      target: downstreamNodeId,
    })
  }
  
  // 重新计算布局
  nextTick(() => {
    layoutGraph()
  })
}

// 删除节点
function deleteNode(nodeId) {
  // 防止删除开始和结束节点
  if (nodeId === 'start' || nodeId === 'end') {
    console.warn('开始节点和结束节点不能删除')
    return
  }

  // 检查是否是互斥决策节点
  const nodeToDelete = nodes.value.find(n => n.id === nodeId)
  if (nodeToDelete && nodeToDelete.type === 'mutex-decision') {
    deleteMutexNode(nodeId)
    return
  }

  // 找到要删除节点的上游和下游连接
  const incomingEdges = edges.value.filter(e => e.target === nodeId)
  const outgoingEdges = edges.value.filter(e => e.source === nodeId)

  // 找到上游和下游的添加按钮节点
  const upstreamAddBtnNodes = incomingEdges
    .map(e => nodes.value.find(n => n.id === e.source && n.type === 'add-button'))
    .filter(Boolean)

  const downstreamAddBtnNodes = outgoingEdges
    .map(e => nodes.value.find(n => n.id === e.target && n.type === 'add-button'))
    .filter(Boolean)

  // 获取真实的上游和下游节点（跳过添加按钮）
  let upstreamNodeId = null
  let downstreamNodeId = null

  // 找上游节点
  if (upstreamAddBtnNodes.length > 0) {
    const addBtnId = upstreamAddBtnNodes[0].id
    const edgeToAddBtn = edges.value.find(e => e.target === addBtnId)
    if (edgeToAddBtn) {
      upstreamNodeId = edgeToAddBtn.source
    }
  }

  // 找下游节点
  if (downstreamAddBtnNodes.length > 0) {
    const addBtnId = downstreamAddBtnNodes[0].id
    const edgeFromAddBtn = edges.value.find(e => e.source === addBtnId)
    if (edgeFromAddBtn) {
      downstreamNodeId = edgeFromAddBtn.target
    }
  }

  // 删除节点和相关的添加按钮节点
  const nodesToDelete = [
    nodeId,
    ...upstreamAddBtnNodes.map(n => n.id),
    ...downstreamAddBtnNodes.map(n => n.id)
  ]

  nodes.value = nodes.value.filter(n => !nodesToDelete.includes(n.id))

  // 删除相关的边
  edges.value = edges.value.filter(e =>
    !nodesToDelete.includes(e.source) &&
    !nodesToDelete.includes(e.target)
  )

  // 如果有上下游节点，在它们之间添加新的添加按钮
  if (upstreamNodeId && downstreamNodeId) {
    const newAddBtnId = `add-btn-${Date.now()}`
    nodes.value.push({
      id: newAddBtnId,
      type: 'add-button',
      position: { x: 0, y: 0 },
      data: {},
    })

    edges.value.push({
      id: `${upstreamNodeId}->${newAddBtnId}`,
      source: upstreamNodeId,
      target: newAddBtnId,
    })

    edges.value.push({
      id: `${newAddBtnId}->${downstreamNodeId}`,
      source: newAddBtnId,
      target: downstreamNodeId,
    })
  }

  // 重新计算布局
  nextTick(() => {
    layoutGraph()
  })
}

// 页面加载时初始化
initializeNodesAndEdges()
</script>

<template>
  <div class="layout-flow">
    <VueFlow :nodes="nodes" :edges="edges" @nodes-initialized="layoutGraph">
      <Background />

      <!-- 注册自定义节点 -->
      <template #node-custom="nodeProps">
        <CustomNode v-bind="nodeProps" @delete-node="deleteNode" />
      </template>

      <!-- 注册添加按钮节点 -->
      <template #node-add-button="nodeProps">
        <AddButtonNode v-bind="nodeProps" @add-node="addNodeAfter" />
      </template>

      <!-- 注册开始节点 -->
      <template #node-start="nodeProps">
        <StartNode v-bind="nodeProps" />
      </template>

      <!-- 注册结束节点 -->
      <template #node-end="nodeProps">
        <EndNode v-bind="nodeProps" />
      </template>

      <!-- 注册审批节点 -->
      <template #node-approval="nodeProps">
        <ApprovalNode v-bind="nodeProps" @delete-node="deleteNode" />
      </template>

      <!-- 注册抄送节点 -->
      <template #node-cc="nodeProps">
        <CcNode v-bind="nodeProps" @delete-node="deleteNode" />
      </template>

      <!-- 注册互斥决策节点 -->
      <template #node-mutex-decision="nodeProps">
        <MutexDecisionNode v-bind="nodeProps" @delete-node="deleteNode" @add-condition="addCondition" />
      </template>

      <!-- 注册互斥分支节点 -->
      <template #node-mutex-branch="nodeProps">
        <MutexBranchNode v-bind="nodeProps" />
      </template>
    </VueFlow>
  </div>
</template>

<style>
.layout-flow {
  height: 100%;
  width: 100%;
}

.process-panel,
.layout-panel {
  display: flex;
  gap: 10px;
}

.process-panel {
  background-color: #2d3748;
  padding: 10px;
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
}

.process-panel button {
  border: none;
  cursor: pointer;
  background-color: #4a5568;
  border-radius: 8px;
  color: white;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}

.process-panel button {
  font-size: 16px;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.checkbox-panel {
  display: flex;
  align-items: center;
  gap: 10px;
}

.process-panel button:hover,
.layout-panel button:hover {
  background-color: #2563eb;
  transition: background-color 0.2s;
}

.process-panel label {
  color: white;
  font-size: 12px;
}

.stop-btn svg {
  display: none;
}

.stop-btn:hover svg {
  display: block;
}

.stop-btn:hover .spinner {
  display: none;
}

.spinner {
  border: 3px solid #f3f3f3;
  border-top: 3px solid #2563eb;
  border-radius: 50%;
  width: 10px;
  height: 10px;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>
